package net.lainiao.service.elastic;

import com.alibaba.fastjson.JSONObject;
import com.github.pagehelper.PageInfo;
import net.lainiao.base.model.ReptilemodelinfosWithBLOBs;
import net.lainiao.base.search.ResultModel;
import net.lainiao.base.search.SearchModel;
import net.lainiao.service.service.ReptileindexService;
import net.lainiao.service.service.ReptilemodeinfoService;
import org.elasticsearch.action.index.IndexRequestBuilder;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.client.Client;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.text.Text;
import org.elasticsearch.common.transport.InetSocketTransportAddress;
import org.elasticsearch.index.query.QueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.SearchHits;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightField;
import org.elasticsearch.transport.client.PreBuiltTransportClient;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * Created by Administrator on 2017/1/17.
 */
@Service
public class ElasticService {
    @Resource
    private ReptilemodeinfoService reptilemodeinfoService;
    @Resource
    private ReptileindexService reptileindexService;
    private Client client = null;
    private IndexRequestBuilder indexRequestBuilder = null;
    static Logger logger= LoggerFactory.getLogger(ElasticService.class);
    public synchronized void addDoc(){
        init();
        try {
            List<ReptilemodelinfosWithBLOBs> reptilemodelinfoses = reptilemodeinfoService.getNoAccess();
            if (reptilemodelinfoses.size() == 0) {
                return;
            }
            if(reptilemodelinfoses!=null){
                for (ReptilemodelinfosWithBLOBs myModel : reptilemodelinfoses) {
                    SearchModel model = new SearchModel();
                    model.setLink(myModel.getLink());
                    model.setTitle(new String(myModel.getTitle()));
                    model.setContent(new String(myModel.getContent()));
                    String json = JSONObject.toJSONString(model);
                    String docId = myModel.getId().toString();
                    indexRequestBuilder.setSource(json).setId(docId).execute().actionGet();
                }
            }
            reptileindexService.adds(reptilemodelinfoses);
            reptilemodeinfoService.setAccess(reptilemodelinfoses);
        }
        catch (Exception e){
            logger.error("{}",e.toString());
        }
    }

    public PageInfo<ResultModel> search(int pageIndex, int pageSize, String s) {
        init();
        PageInfo<ResultModel> pageInfo=new PageInfo<>();
        try {
            List<ResultModel> list=new ArrayList<>();
            QueryBuilder queryBuilder= QueryBuilders.multiMatchQuery(s,"title","content");
            HighlightBuilder highlightBuilder=new HighlightBuilder();
            highlightBuilder.field("title").field("content");
            SearchResponse response=client.prepareSearch("codesearch").setTypes("doc").setQuery(queryBuilder).highlighter(highlightBuilder).setFrom(pageIndex).setSize(pageSize).execute().actionGet();
            SearchHits searchHits=response.getHits();
            for(SearchHit searchHit : searchHits){
                Map map=searchHit.getSource();
                ResultModel resultModel=new ResultModel();
                resultModel.setLink(map.get("link").toString());
                resultModel.setTitle(map.get("title").toString());
                resultModel.setContent(map.get("content").toString());
                Map map1=searchHit.getHighlightFields();
                if(map1.get("content")!=null){
                    Text[] htmls=((HighlightField)map1.get("content")).getFragments();
                    StringBuilder stringBuilder=new StringBuilder();
                    for(Text text:htmls){
                        stringBuilder.append(text.toString());
                    }
                    resultModel.setContent(stringBuilder.toString());
                }

                if(map1.get("title")!=null){
                    Text[] htmls=((HighlightField)map1.get("title")).getFragments();
                    StringBuilder stringBuilder=new StringBuilder();
                    for(Text text:htmls){
                        stringBuilder.append(text.toString());
                    }
                    resultModel.setTitle(stringBuilder.toString());
                }
                list.add(resultModel);
            }
            pageInfo.setList(list);
            long total=response.getHits().totalHits();
            pageInfo.setTotal(total);
            int pageTotal=(int) Math.ceil(total/10.00d);
            pageInfo.setPages(pageTotal);
        } catch (Exception e) {
            e.printStackTrace();
            logger.error("{}",e.toString());
        }
        return pageInfo;
    }

    public synchronized void init(){
        if(client!=null){
            return;
        }
        try {
            Settings settings = Settings.builder().put("cluster.name", "elasticsearch").build();
            InetAddress address = InetAddress.getByName("127.0.0.1");
            client = new PreBuiltTransportClient(settings).addTransportAddress(new InetSocketTransportAddress(address, 9300));
            indexRequestBuilder = client.prepareIndex("codesearch", "doc");
        }
        catch (UnknownHostException e) {
            e.printStackTrace();
            client=null;
            indexRequestBuilder=null;
            logger.error("{}",e.toString());
        }
    }

    public synchronized  void close(){
        if(client!=null){
            return;
        }
        try {
            client.close();
        } finally {
            client=null;
            indexRequestBuilder=null;
        }
    }
}
